package wiki.hitime.stl.daq.service.factory.impl.check;

import com.alibaba.fastjson.JSON;
import com.udojava.evalex.Expression;
import lombok.extern.slf4j.Slf4j;
import wiki.hitime.stl.daq.bean.bo.DataAcquisitionValueBO;
import wiki.hitime.stl.daq.bean.bo.DataCheckValueBO;
import wiki.hitime.stl.daq.enums.DataValueTypeEnum;
import wiki.hitime.stl.daq.service.factory.DataCheckFactory;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.Map;

/**
 * 数据检查抽象类
 *
 * @author zhangdaoping
 * @create 2019-07-19 10:48
 */
@Slf4j
public abstract class AbstractDataCheckService implements DataCheckFactory {

    void validateArgs(DataAcquisitionValueBO acquisitionValueBO, DataCheckValueBO dataCheckValueBO) {
        Assert.notNull(acquisitionValueBO, "采集值为空");
        Assert.notEmpty(acquisitionValueBO.getDataList(), "采集值为空");
        Assert.notEmpty(acquisitionValueBO.getDataList().get(0), "采集值为空");
        Assert.notNull(acquisitionValueBO.getValueType(), "采集值类型为空");
        Assert.isTrue(!acquisitionValueBO.getValueType().equals(0), "采集值类型为空");
        Assert.notNull(dataCheckValueBO, "比对值为空");
        Assert.notEmpty(dataCheckValueBO.getDataList(), "比对值为空");
    }


    /**
     * 格式化金额
     *
     * @param value 原始值
     * @return 金额
     */
    BigDecimal valueFormatBigDecimal(String value) {
        try {
            return new BigDecimal(value);
        } catch (Exception e) {
            throw new RuntimeException("值转换错误，value=" + value);
        }
    }

    /**
     * 格式化日期时间
     *
     * @param value       原始值
     * @param valueFormat 日期时间格式
     * @return 日期时间
     */
    DateTime valueFormatDateTime(String value, String valueFormat) {
        try {
            Assert.hasText(valueFormat, "时间转换表达式为空");
            return DateTime.parse(value, DateTimeFormat.forPattern(valueFormat));
        } catch (Exception e) {
            throw new RuntimeException("值转换错误，value=" + value + "，valueFormat=" + valueFormat);
        }
    }

    /**
     * 格式化布尔值
     *
     * @param value 原始值
     * @return 布尔值
     */
    Boolean valueFormatBoolean(String value) {
        try {
            return Boolean.parseBoolean(value);
        } catch (Exception e) {
            throw new RuntimeException("值转换错误，value=" + value);
        }
    }

    /**
     * 加载常规比较摘要
     *
     * @param acquisitionValue 采集值
     * @param checkValue       检查值
     * @param checkResult      检查结果
     * @return 检查摘要
     */
    String loadSummary(Object acquisitionValue, Object checkValue, Boolean checkResult) {
        return String.format("%s%s%s比较结果为%s", acquisitionValue, this.getCheckConfig().getCheckName(), checkValue, checkResult);
    }

    /**
     * 加载不支持比较的摘要
     *
     * @param dataValueTypeEnum 值类型
     * @return 检查摘要
     */
    String loadNotSupportSummary(DataValueTypeEnum dataValueTypeEnum) {
        return String.format("%s比较方式不支持%s", this.getCheckConfig().getCheckName(), dataValueTypeEnum.getMsg());
    }

    /**
     * 加载值类型枚举
     *
     * @param valueType
     * @return
     */
    DataValueTypeEnum loadValueTypeEnum(Integer valueType) {
        DataValueTypeEnum valueTypeEnum = DataValueTypeEnum.valueOf(valueType);
        Assert.notNull(valueTypeEnum, "值类型枚举为空");
        return valueTypeEnum;
    }

    /**
     * 根据值map和公式计算对应金额
     *
     * @param valuesMap        入参
     * @param expressionString 表达式
     * @return 计算结果，如果是布尔类型返回0-false，1-true
     */
    BigDecimal getCalcResult(Map<String, BigDecimal> valuesMap, String expressionString) {
        Expression expression = new Expression(expressionString);
        for (Map.Entry<String, BigDecimal> entry : valuesMap.entrySet()) {
            expression.with(entry.getKey(), entry.getValue());
        }
        BigDecimal value = expression.eval();
        log.info("值：{}，公式：{}，计算值：{}", JSON.toJSONString(valuesMap), expressionString, value);
        return value;
    }
}
